/****************************************************************************
 * Copyright (C) 2009-2013 Dimok
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 ****************************************************************************/
#include <ogcsys.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "Settings.h"
#include "FileOperations/fileops.h"
#include "DeviceControls/DeviceHandler.hpp"
#include "Language/gettext.h"
#include "Tools/StringTools.h"
#include "Tools/tools.h"
#include "Tools/encrypt.h"

#define DEFAULT_APP_PATH	"apps/WiiXplorer/"
#define CONFIGPATH			DEFAULT_APP_PATH
#define CONFIGNAME			"WiiXplorer.cfg"
#define LANGPATH			"Languages/"

CSettings Settings;

CSettings::CSettings()
{
	strcpy(BootDevice, "sd:/");
	snprintf(ConfigPath, sizeof(ConfigPath), "%s%s%s", BootDevice, CONFIGPATH, CONFIGNAME);
	this->SetDefault();
}

CSettings::~CSettings()
{
}

void CSettings::SetDefault()
{
	BootIOS = 58;
	MusicVolume = 80;
	CurrentSMBUser = 0;
	CurrentFTPUser = 0;
	CurrentNFSUser = 0;
	BGMLoopMode = 1;
	SlideshowDelay = 4;
	ImageFadeSpeed = 20;
	KeyboardDeleteDelay = 15;
	AutoConnect = 0;
	UpdateMetaxml = 1;
	UpdateIconpng = 1;
	ClockMode = 0;
	ScrollSpeed = 5;
	BrowserMode = ICONBROWSER;
	ScreenshotFormat = 0;
	SoundblockCount = 32;
	SoundblockSize = 8192;
	LoadMusicToMem = 0;
	DeleteTempPath = 1;
	CopyThreadPrio = 70;
	CopyThreadBackPrio = 30;
	Rumble = 0;
	HideSystemFiles = 1;
	ShowFormatter = 0;
	CompressionLevel = -1;
	USBPort = 0;
	MountISFS = ON;
	ISFSWriteAccess = OFF;
	ResampleTo48kHz = ON;
	OverridePriiloader = ON;
	TooltipDelay = 1000;
	PDFLoadZoom = 1.0f;
	PointerSpeed = 0.18f;
	sprintf(CustomFontPath, "%s%sfont.ttf", BootDevice, CONFIGPATH);
	sprintf(LanguagePath, "%s%s%s", BootDevice, DEFAULT_APP_PATH, LANGPATH);
	sprintf(UpdatePath, "%s%s", BootDevice, DEFAULT_APP_PATH);
	sprintf(HomebrewAppsPath, "%sapps/", BootDevice);
	sprintf(TempPath, "%sTemp/", UpdatePath);
	sprintf(ScreenshotPath, "%s", UpdatePath);
	sprintf(LinkListPath, "%sURL_List.xml", UpdatePath);
	strcpy(MusicPath, "");
	sprintf(MPlayerPath, "%sapps/mplayer_ce/boot.dol", BootDevice);
	sprintf(WiiMCPath, "%sapps/wiimc/boot.dol", BootDevice);
	LastUsedPath = BootDevice;

	for(int i = 0; i < MAXSMBUSERS; i++) {
		strcpy(SMBUser[i].Host, "");
		strcpy(SMBUser[i].User, "");
		strcpy(SMBUser[i].Password, "");
		strcpy(SMBUser[i].SMBName, "");
	}

	for(int i = 0; i < MAXFTPUSERS; i++) {
		strcpy(FTPUser[i].Host, "");
		strcpy(FTPUser[i].User, "");
		strcpy(FTPUser[i].Password, "");
		strcpy(FTPUser[i].FTPPath, "/");
		FTPUser[i].Port = 21;
		FTPUser[i].Passive = 0;
	}

	FTPServer.AutoStart = 0;
	strcpy(FTPServer.Password, "");
	FTPServer.Port = 21;

	for(int i = 0; i < MAXNFSUSERS; i++) {
		strcpy(NFSUser[i].Host, "");
		strcpy(NFSUser[i].Mountpoint, "");
	}

	FileExtensions.SetDefault();
	Controls.SetDefault();

	DefaultColors();
}

void CSettings::DefaultColors()
{
	BackgroundUL = GXCOLORTORGBA(((GXColor){67, 71, 72, 255}));
	BackgroundUR = GXCOLORTORGBA(((GXColor){67, 71, 72, 255}));
	BackgroundBR = GXCOLORTORGBA(((GXColor){100, 110, 110, 255}));
	BackgroundBL = GXCOLORTORGBA(((GXColor){100, 110, 110, 255}));
	ProgressUL = GXCOLORTORGBA(((GXColor){239, 28, 28, 255}));
	ProgressUR = GXCOLORTORGBA(((GXColor){79, 153, 239, 255}));
	ProgressBR = GXCOLORTORGBA(((GXColor){59, 159, 223, 255}));
	ProgressBL = GXCOLORTORGBA(((GXColor){199, 71, 99, 255}));
	ProgressEmptyUL = GXCOLORTORGBA(((GXColor){237, 240, 245, 255}));
	ProgressEmptyUR = GXCOLORTORGBA(((GXColor){237, 240, 245, 255}));
	ProgressEmptyBR = GXCOLORTORGBA(((GXColor){197, 202, 210, 255}));
	ProgressEmptyBL = GXCOLORTORGBA(((GXColor){197, 202, 210, 255}));
}

bool CSettings::Save()
{
	if(!FindConfig())
		return false;

	char filedest[100];
	char password[100];
	snprintf(filedest, sizeof(filedest), "%s", ConfigPath);

	char * tmppath = strrchr(filedest, '/');
	if(tmppath)
	{
		tmppath++;
		tmppath[0] = '\0';
	}

	if(!CreateSubfolder(filedest))
		return false;

	FILE *file = fopen(ConfigPath, "w");
	if(!file)
	{
		fclose(file);
		return false;
	}

	fprintf(file, "# WiiXplorer Settingsfile\n");
	fprintf(file, "# Note: This file is automatically generated\n\n");
	fprintf(file, "# Main Settings\n\n");
	fprintf(file, "BootIOS = %d\n", BootIOS);
	fprintf(file, "CurrentSMBUser = %d\n", CurrentSMBUser);
	fprintf(file, "CurrentFTPUser = %d\n", CurrentFTPUser);
	fprintf(file, "CurrentNFSUser = %d\n", CurrentNFSUser);
	fprintf(file, "LanguagePath = %s\n", LanguagePath);
	fprintf(file, "MusicVolume = %d\n", MusicVolume);
	fprintf(file, "BGMLoopMode = %d\n", BGMLoopMode);
	fprintf(file, "AutoConnect = %d\n", AutoConnect);
	fprintf(file, "UpdateMetaxml = %d\n", UpdateMetaxml);
	fprintf(file, "UpdateIconpng = %d\n", UpdateIconpng);
	fprintf(file, "ClockMode = %d\n", ClockMode);
	fprintf(file, "ScrollSpeed = %d\n", ScrollSpeed);
	fprintf(file, "BrowserMode = %d\n", BrowserMode);
	fprintf(file, "SoundblockCount = %d\n", SoundblockCount);
	fprintf(file, "SoundblockSize = %d\n", SoundblockSize);
	fprintf(file, "LoadMusicToMem = %d\n", LoadMusicToMem);
	fprintf(file, "PDFLoadZoom = %g\n", PDFLoadZoom);
	fprintf(file, "PointerSpeed = %g\n", PointerSpeed);
	fprintf(file, "ScreenshotFormat = %d\n", ScreenshotFormat);
	fprintf(file, "LastUsedPath = %s\n", LastUsedPath.c_str());
	fprintf(file, "MusicPath = %s\n", MusicPath);
	fprintf(file, "WiiMCPath = %s\n", WiiMCPath);
	fprintf(file, "MPlayerPath = %s\n", MPlayerPath);
	fprintf(file, "CustomFontPath = %s\n", CustomFontPath);
	fprintf(file, "UpdatePath = %s\n", UpdatePath);
	fprintf(file, "AppPath = %s\n", HomebrewAppsPath);
	fprintf(file, "TempPath = %s\n", TempPath);
	fprintf(file, "ScreenshotPath = %s\n", ScreenshotPath);
	fprintf(file, "LinkListPath = %s\n", LinkListPath);
	fprintf(file, "SlideshowDelay = %d\n", SlideshowDelay);
	fprintf(file, "ImageFadeSpeed = %d\n", ImageFadeSpeed);
	fprintf(file, "KeyboardDeleteDelay = %d\n", KeyboardDeleteDelay);
	fprintf(file, "DeleteTempPath = %d\n", DeleteTempPath);
	fprintf(file, "CopyThreadPrio = %d\n", CopyThreadPrio);
	fprintf(file, "CopyThreadBackPrio = %d\n", CopyThreadBackPrio);
	fprintf(file, "Rumble = %d\n", Rumble);
	fprintf(file, "HideSystemFiles = %d\n", HideSystemFiles);
	fprintf(file, "ShowFormatter = %d\n", ShowFormatter);
	fprintf(file, "CompressionLevel = %d\n", CompressionLevel);
	fprintf(file, "USBPort = %d\n", USBPort);
	fprintf(file, "MountISFS = %d\n", MountISFS);
	fprintf(file, "TooltipDelay = %d\n", TooltipDelay);
	fprintf(file, "ResampleTo48kHz = %d\n", ResampleTo48kHz);
	fprintf(file, "OverridePriiloader = %d\n", OverridePriiloader);

	fprintf(file, "\n# Fileextensions assignment.\n\n");
	fprintf(file, "FileExtensions.VideoFiles = %s\n", FileExtensions.GetVideo());
	fprintf(file, "FileExtensions.AudioFiles = %s\n", FileExtensions.GetAudio());
	fprintf(file, "FileExtensions.ImageFiles = %s\n", FileExtensions.GetImage());
	fprintf(file, "FileExtensions.ArchiveFiles = %s\n", FileExtensions.GetArchive());
	fprintf(file, "FileExtensions.HomebrewFiles = %s\n", FileExtensions.GetHomebrew());
	fprintf(file, "FileExtensions.FontFiles = %s\n", FileExtensions.GetFont());
	fprintf(file, "FileExtensions.LanguageFiles = %s\n", FileExtensions.GetLanguageFiles());
	fprintf(file, "FileExtensions.WiiBinaryFiles = %s\n", FileExtensions.GetWiiBinary());
	fprintf(file, "FileExtensions.PDFFiles = %s\n", FileExtensions.GetPDF());
	fprintf(file, "FileExtensions.WiiXplorerMovies = %s\n", FileExtensions.GetWiiXplorerMovies());

	fprintf(file, "\n# Color Settings.\n\n");
	fprintf(file, "BackgroundUL = %u\n", BackgroundUL);
	fprintf(file, "BackgroundUR = %u\n", BackgroundUR);
	fprintf(file, "BackgroundBR = %u\n", BackgroundBR);
	fprintf(file, "BackgroundBL = %u\n", BackgroundBL);
	fprintf(file, "ProgressUL = %u\n", ProgressUL);
	fprintf(file, "ProgressUR = %u\n", ProgressUR);
	fprintf(file, "ProgressBR = %u\n", ProgressBR);
	fprintf(file, "ProgressBL = %u\n", ProgressBL);
	fprintf(file, "ProgressEmptyUL = %u\n", ProgressEmptyUL);
	fprintf(file, "ProgressEmptyUR = %u\n", ProgressEmptyUR);
	fprintf(file, "ProgressEmptyBR = %u\n", ProgressEmptyBR);
	fprintf(file, "ProgressEmptyBL = %u\n", ProgressEmptyBL);

	fprintf(file, "\n# SMB Setup Information\n\n");
	for(int i = 0; i < MAXSMBUSERS; i++) {
		fprintf(file, "SMBUser[%d].Host = %s\n", i+1, SMBUser[i].Host);
		fprintf(file, "SMBUser[%d].User = %s\n", i+1, SMBUser[i].User);
		password[0] = 0;
		if (strcmp(SMBUser[i].Password, "") != 0)
			EncryptString(SMBUser[i].Password, password);
		fprintf(file, "SMBUser[%d].CPassword = %s\n", i+1, password);
		fprintf(file, "SMBUser[%d].SMBName = %s\n\n", i+1, SMBUser[i].SMBName);
	}

	fprintf(file, "\n# FTP Setup Information\n\n");
	for(int i = 0; i < MAXFTPUSERS; i++) {
		fprintf(file, "FTPUser[%d].Host = %s\n", i+1, FTPUser[i].Host);
		fprintf(file, "FTPUser[%d].User = %s\n", i+1, FTPUser[i].User);
		password[0] = 0;
		if (strcmp(FTPUser[i].Password, "") != 0)
			EncryptString(FTPUser[i].Password, password);
		fprintf(file, "FTPUser[%d].CPassword = %s\n", i+1, password);
		fprintf(file, "FTPUser[%d].FTPPath = %s\n", i+1, FTPUser[i].FTPPath);
		fprintf(file, "FTPUser[%d].Port = %d\n", i+1, FTPUser[i].Port);
		fprintf(file, "FTPUser[%d].Passive = %d\n\n", i+1, FTPUser[i].Passive);
	}

	fprintf(file, "\n# FTP Server Setup Information\n\n");
	fprintf(file, "FTPServer.AutoStart = %d\n", FTPServer.AutoStart);
	password[0] = 0;
	if (strcmp(FTPServer.Password, "") != 0)
		EncryptString(FTPServer.Password, password);
	fprintf(file, "FTPServer.CPassword = %s\n", password);
	fprintf(file, "FTPServer.Port = %d\n", FTPServer.Port);

	fprintf(file, "\n# NFS Setup Information\n\n");
	for (int i = 0; i < MAXNFSUSERS; i++) {
		fprintf(file, "NFSUser[%d].Host = %s\n", i+1, NFSUser[i].Host);
		fprintf(file, "NFSUser[%d].Mountpoint = %s\n", i+1, NFSUser[i].Mountpoint);
	}


	fclose(file);

	Controls.Save();

	return true;
}

bool CSettings::FindConfig()
{
	bool found = false;
	char CheckDevice[12];
	memset(BootDevice, 0, sizeof(BootDevice));

	// Enumerate the devices supported by libogc.
	for (int i = SD; (i < USB8) && !found; ++i)
	{
		snprintf(CheckDevice, sizeof(CheckDevice), "%s:", DeviceName[i]);

		if(!found)
		{
			// Check for the config file in the apps directory.
			strncpy(BootDevice, CheckDevice, sizeof(BootDevice)-1);
			snprintf(ConfigPath, sizeof(ConfigPath), "%s/apps/WiiXplorer/%s", BootDevice, CONFIGNAME);
			found = CheckFile(ConfigPath);
		}
		if(!found)
		{
			// Check for the config file in the apps directory.
			strncpy(BootDevice, CheckDevice, sizeof(BootDevice)-1);
			snprintf(ConfigPath, sizeof(ConfigPath), "%s/apps/WiiExplorer/%s", BootDevice, CONFIGNAME);
			found = CheckFile(ConfigPath);
		}
		if(!found)
		{
			// Check for the config file in the config directory.
			strncpy(BootDevice, CheckDevice, sizeof(BootDevice)-1);
			snprintf(ConfigPath, sizeof(ConfigPath), "%s/%s%s", BootDevice, CONFIGPATH, CONFIGNAME);
			found = CheckFile(ConfigPath);
		}
	}

	FILE * testFp = NULL;
	// No existing config so try to find a place where we can write it too
	for (int i = SD; (i < USB8) && !found; ++i)
	{
		sprintf(CheckDevice, "%s:", DeviceName[i]);

		if (!found)
		{
			// Check if we can write to the apps directory.
			strncpy(BootDevice, CheckDevice, sizeof(BootDevice)-1);
			snprintf(ConfigPath, sizeof(ConfigPath), "%s/apps/WiiXplorer/%s", BootDevice, CONFIGNAME);
			testFp = fopen(ConfigPath, "wb");
			found = (testFp != NULL);
			if(testFp) fclose(testFp);
		}
		if (!found)
		{
			// Check if we can write to the apps directory.
			strncpy(BootDevice, CheckDevice, sizeof(BootDevice)-1);
			snprintf(ConfigPath, sizeof(ConfigPath), "%s/apps/WiiExplorer/%s", BootDevice, CONFIGNAME);
			testFp = fopen(ConfigPath, "wb");
			found = (testFp != NULL);
			if(testFp) fclose(testFp);
		}
		if (!found)
		{
			// Check if we can write to the config directory.
			strncpy(BootDevice, CheckDevice, sizeof(BootDevice)-1);
			snprintf(ConfigPath, sizeof(ConfigPath), "%s/%s", BootDevice, CONFIGPATH);
			CreateSubfolder(ConfigPath);
			snprintf(ConfigPath, sizeof(ConfigPath), "%s/%s%s", BootDevice, CONFIGPATH, CONFIGNAME);
			testFp = fopen(ConfigPath, "wb");
			found = (testFp != NULL);
			if(testFp) fclose(testFp);
		}
	}

	return found;
}

bool CSettings::Load()
{
	FindConfig();

	char line[1024];
	char filepath[150];
	snprintf(filepath, sizeof(filepath), "%s", ConfigPath);

	FILE *file = fopen(filepath, "r");
	if (!file)
		return false;

	while (fgets(line, sizeof(line), file))
	{
		if (line[0] == '#') continue;

		this->ParseLine(line);
	}
	fclose(file);

	char * ptr = strrchr(filepath, '/');
	if(ptr)
		ptr[0] = '\0';

	Controls.Load(filepath);

	return true;

}

bool CSettings::LoadLanguage(const char *path, int language)
{
	bool ret = false;

	if(language >= 0 || !path) {

		if(language < 0)
			return false;

		char filepath[150];
		char langpath[150];
		memset(langpath, 0, sizeof(langpath));
		snprintf(langpath, sizeof(langpath), "%s", LanguagePath);
		//! append slash if it is not a .lang file otherwise get the path of the .lang file
		if(strextcmp(langpath, "lang", '.') == 0)
		{
			char * ptr = strrchr(langpath, '/');
			if(ptr)
			{
				ptr++;
				ptr[0] = '\0';
			}
		}
		else {
			if(strlen(langpath) > 0 && langpath[strlen(langpath)-1] != '/')
				strncat(langpath, "/", sizeof(langpath)-1);
		}

		if(language == APP_DEFAULT)
		{
			strcpy(LanguagePath, langpath);
			gettextCleanUp();
			return true;
		}
		else if(language == CONSOLE_DEFAULT)
		{
			return LoadLanguage(NULL, CONF_GetLanguage()+2);
		}
		else if(language == JAPANESE)
		{
			snprintf(filepath, sizeof(filepath), "%s/japanese.lang", langpath);
		}
		else if(language == ENGLISH)
		{
			snprintf(filepath, sizeof(filepath), "%s/english.lang", langpath);
		}
		else if(language == GERMAN)
		{
			snprintf(filepath, sizeof(filepath), "%s/german.lang", langpath);
		}
		else if(language == FRENCH)
		{
			snprintf(filepath, sizeof(filepath), "%s/french.lang", langpath);
		}
		else if(language == SPANISH)
		{
			snprintf(filepath, sizeof(filepath), "%s/spanish.lang", langpath);
		}
		else if(language == ITALIAN)
		{
			snprintf(filepath, sizeof(filepath), "%s/italian.lang", langpath);
		}
		else if(language == DUTCH)
		{
			snprintf(filepath, sizeof(filepath), "%s/dutch.lang", langpath);
		}
		else if(language == S_CHINESE)
		{
			snprintf(filepath, sizeof(filepath), "%s/s_chinese.lang", langpath);
		}
		else if(language == T_CHINESE)
		{
			snprintf(filepath, sizeof(filepath), "%s/t_chinese.lang", langpath);
		}
		else if(language == KOREAN)
		{
			snprintf(filepath, sizeof(filepath), "%s%s/korean.lang", BootDevice, langpath);
		}

		ret = gettextLoadLanguage(filepath);
		if(ret)
			strncpy(LanguagePath, filepath, sizeof(LanguagePath));

	} else {

		ret = gettextLoadLanguage(path);
		if(ret)
			strncpy(LanguagePath, path, sizeof(LanguagePath));
	}

	return ret;
}

bool CSettings::Reset()
{
	this->SetDefault();

	if(this->Save())
		return true;

	return false;
}

bool CSettings::SetSetting(char *name, char *value)
{
	int i = 0;
	char password[100];

	if (strcmp(name, "BootIOS") == 0) {
		BootIOS = atoi(value);
		return true;
	}
	else if (strcmp(name, "CurrentSMBUser") == 0) {
		CurrentSMBUser = atoi(value);
		return true;
	}
	else if (strcmp(name, "CurrentFTPUser") == 0) {
		CurrentFTPUser = atoi(value);
		return true;
	}
	else if (strcmp(name, "LanguagePath") == 0) {
		strncpy(LanguagePath, value, sizeof(LanguagePath));
		return true;
	}
	else if (strcmp(name, "MusicVolume") == 0) {
		MusicVolume = atoi(value);
		return true;
	}
	else if (strcmp(name, "BGMLoopMode") == 0) {
		BGMLoopMode = atoi(value);
		return true;
	}
	else if (strcmp(name, "AutoConnect") == 0) {
		AutoConnect = atoi(value);
		return true;
	}
	else if (strcmp(name, "UpdateMetaxml") == 0) {
		UpdateMetaxml = atoi(value);
		return true;
	}
	else if (strcmp(name, "UpdateIconpng") == 0) {
		UpdateIconpng = atoi(value);
		return true;
	}
	else if (strcmp(name, "ClockMode") == 0) {
		ClockMode = atoi(value);
		return true;
	}
	else if (strcmp(name, "ScrollSpeed") == 0) {
		ScrollSpeed = atoi(value);
		return true;
	}
	else if (strcmp(name, "BrowserMode") == 0) {
		BrowserMode = atoi(value);
		return true;
	}
	else if (strcmp(name, "ScreenshotFormat") == 0) {
		ScreenshotFormat = atoi(value);
		return true;
	}
	else if (strcmp(name, "SoundblockCount") == 0) {
		SoundblockCount = atoi(value);
		return true;
	}
	else if (strcmp(name, "SoundblockSize") == 0) {
		SoundblockSize = atoi(value);
		return true;
	}
	else if (strcmp(name, "LoadMusicToMem") == 0) {
		LoadMusicToMem = atoi(value);
		return true;
	}
	else if (strcmp(name, "PDFLoadZoom") == 0) {
		PDFLoadZoom = atof(value);
		return true;
	}
	else if (strcmp(name, "PointerSpeed") == 0) {
		PointerSpeed = atof(value);
		return true;
	}
	else if (strcmp(name, "CustomFontPath") == 0) {
		strncpy(CustomFontPath, value, sizeof(CustomFontPath));
		return true;
	}
	else if (strcmp(name, "LastUsedPath") == 0) {
		LastUsedPath.assign(value);
		return true;
	}
	else if (strcmp(name, "MusicPath") == 0) {
		strncpy(MusicPath, value, sizeof(MusicPath));
		return true;
	}
	else if (strcmp(name, "WiiMCPath") == 0) {
		strncpy(WiiMCPath, value, sizeof(WiiMCPath));
		return true;
	}
	else if (strcmp(name, "MPlayerPath") == 0) {
		strncpy(MPlayerPath, value, sizeof(MPlayerPath));
		return true;
	}
	else if (strcmp(name, "UpdatePath") == 0) {
		strncpy(UpdatePath, value, sizeof(UpdatePath));
		return true;
	}
	else if (strcmp(name, "AppPath") == 0) {
		strncpy(HomebrewAppsPath, value, sizeof(HomebrewAppsPath));
		return true;
	}
	else if (strcmp(name, "TempPath") == 0) {
		strncpy(TempPath, value, sizeof(TempPath));
		return true;
	}
	else if (strcmp(name, "ScreenshotPath") == 0) {
		strncpy(ScreenshotPath, value, sizeof(ScreenshotPath));
		return true;
	}
	else if (strcmp(name, "LinkListPath") == 0) {
		strncpy(LinkListPath, value, sizeof(LinkListPath));
		return true;
	}
	else if (strcmp(name, "SlideshowDelay") == 0) {
		SlideshowDelay = atoi(value);
		return true;
	}
	else if (strcmp(name, "ImageFadeSpeed") == 0) {
		ImageFadeSpeed = atoi(value);
		return true;
	}
	else if (strcmp(name, "KeyboardDeleteDelay") == 0) {
		KeyboardDeleteDelay = atoi(value);
		return true;
	}
	else if (strcmp(name, "DeleteTempPath") == 0) {
		DeleteTempPath = atoi(value);
		return true;
	}
	else if (strcmp(name, "CopyThreadPrio") == 0) {
		CopyThreadPrio = atoi(value);
		return true;
	}
	else if (strcmp(name, "CopyThreadBackPrio") == 0) {
		CopyThreadBackPrio = atoi(value);
		return true;
	}
	else if (strcmp(name, "Rumble") == 0) {
		Rumble = atoi(value);
		return true;
	}
	else if (strcmp(name, "HideSystemFiles") == 0) {
		HideSystemFiles = atoi(value);
		return true;
	}
	else if (strcmp(name, "ShowFormatter") == 0) {
		ShowFormatter = atoi(value);
		return true;
	}
	else if (strcmp(name, "CompressionLevel") == 0) {
		CompressionLevel = atoi(value);
		return true;
	}
	else if (strcmp(name, "USBPort") == 0) {
		USBPort = atoi(value);
		return true;
	}
	else if (strcmp(name, "MountISFS") == 0) {
		MountISFS = atoi(value);
		return true;
	}
	else if (strcmp(name, "TooltipDelay") == 0) {
		TooltipDelay = atoi(value);
		return true;
	}
	else if (strcmp(name, "ResampleTo48kHz") == 0) {
		ResampleTo48kHz = atoi(value);
		return true;
	}
	else if (strcmp(name, "OverridePriiloader") == 0) {
		OverridePriiloader = atoi(value);
		return true;
	}
	else if (strcmp(name, "BackgroundUL") == 0) {
		sscanf(value, "%u", &BackgroundUL);
		return true;
	}
	else if (strcmp(name, "BackgroundUR") == 0) {
		sscanf(value, "%u", &BackgroundUR);
		return true;
	}
	else if (strcmp(name, "BackgroundBR") == 0) {
		sscanf(value, "%u", &BackgroundBR);
		return true;
	}
	else if (strcmp(name, "BackgroundBL") == 0) {
		sscanf(value, "%u", &BackgroundBL);
		return true;
	}
	else if (strcmp(name, "ProgressUL") == 0) {
		sscanf(value, "%u", &ProgressUL);
		return true;
	}
	else if (strcmp(name, "ProgressUR") == 0) {
		sscanf(value, "%u", &ProgressUR);
		return true;
	}
	else if (strcmp(name, "ProgressBR") == 0) {
		sscanf(value, "%u", &ProgressBR);
		return true;
	}
	else if (strcmp(name, "ProgressBL") == 0) {
		sscanf(value, "%u", &ProgressBL);
		return true;
	}
	else if (strcmp(name, "ProgressEmptyUL") == 0) {
		sscanf(value, "%u", &ProgressEmptyUL);
		return true;
	}
	else if (strcmp(name, "ProgressEmptyUR") == 0) {
		sscanf(value, "%u", &ProgressEmptyUR);
		return true;
	}
	else if (strcmp(name, "ProgressEmptyBR") == 0) {
		sscanf(value, "%u", &ProgressEmptyBR);
		return true;
	}
	else if (strcmp(name, "ProgressEmptyBL") == 0) {
		sscanf(value, "%u", &ProgressEmptyBL);
		return true;
	}
	else if (strcmp(name, "FileExtensions.VideoFiles") == 0) {
		FileExtensions.SetVideo(value);
		return true;
	}
	else if (strcmp(name, "FileExtensions.AudioFiles") == 0) {
		FileExtensions.SetAudio(value);
		return true;
	}
	else if (strcmp(name, "FileExtensions.ImageFiles") == 0) {
		FileExtensions.SetImage(value);
		return true;
	}
	else if (strcmp(name, "FileExtensions.ArchiveFiles") == 0) {
		FileExtensions.SetArchive(value);
		return true;
	}
	else if (strcmp(name, "FileExtensions.HomebrewFiles") == 0) {
		FileExtensions.SetHomebrew(value);
		return true;
	}
	else if (strcmp(name, "FileExtensions.FontFiles") == 0) {
		FileExtensions.SetFont(value);
		return true;
	}
	else if (strcmp(name, "FileExtensions.WiiBinaryFiles") == 0) {
		FileExtensions.SetWiiBinary(value);
		return true;
	}
	else if (strcmp(name, "FileExtensions.LanguageFiles") == 0) {
		FileExtensions.SetLanguageFiles(value);
		return true;
	}
	else if (strcmp(name, "FileExtensions.PDFFiles") == 0) {
		FileExtensions.SetPDF(value);
		return true;
	}
	else if (strcmp(name, "FileExtensions.WiiXplorerMovies") == 0) {
		FileExtensions.SetWiiXplorerMovies(value);
		return true;
	}
	else if (strcmp(name, "FTPServer.AutoStart") == 0) {
		FTPServer.AutoStart = atoi(value);
		return true;
	}
	else if (strcmp(name, "FTPServer.CPassword") == 0) {
		if (strcmp(value, "") != 0)
			DecryptString(value, password);
		strncpy(FTPServer.Password, ((strcmp(value, "") != 0) ? password : value), sizeof(FTPServer.Password));
		return true;
	}
	else if (strcmp(name, "FTPServer.Port") == 0) {
		FTPServer.Port = atoi(value);
		return true;
	}
	else {
		char temp[80];
		int n = 0;

		for(n = 0; n < MAXSMBUSERS; n++) {
			sprintf(temp, "SMBUser[%d].Host", n+1);
			if (strcasecmp(name, temp) == 0) {
				strncpy(SMBUser[n].Host, value, sizeof(SMBUser[n].Host));
				return true;
			}
			sprintf(temp, "SMBUser[%d].User", n+1);
			if (strcasecmp(name, temp) == 0) {
				strncpy(SMBUser[n].User, value, sizeof(SMBUser[n].User));
				return true;
			}
			sprintf(temp, "SMBUser[%d].CPassword", n+1);
			if (strcasecmp(name, temp) == 0) {
				if (strcmp(value, "") != 0)
					DecryptString(value, password);
				strncpy(SMBUser[n].Password, ((strcmp(value, "") != 0) ? password : value), sizeof(SMBUser[n].Password));
				return true;
			}
			sprintf(temp, "SMBUser[%d].SMBName", n+1);
			if (strcasecmp(name, temp) == 0) {
				strncpy(SMBUser[n].SMBName, value, sizeof(SMBUser[n].SMBName));
				return true;
			}
		}

		for(n = 0; n < MAXFTPUSERS; n++) {
			sprintf(temp, "FTPUser[%d].Host", n+1);
			if (strcasecmp(name, temp) == 0) {
				strncpy(FTPUser[n].Host, value, sizeof(FTPUser[n].Host));
				return true;
			}
			sprintf(temp, "FTPUser[%d].User", n+1);
			if (strcasecmp(name, temp) == 0) {
				strncpy(FTPUser[n].User, value, sizeof(FTPUser[n].User));
				return true;
			}
			sprintf(temp, "FTPUser[%d].CPassword", n+1);
			if (strcasecmp(name, temp) == 0) {
				if (strcmp(value, "") != 0)
					DecryptString(value, password);
				strncpy(FTPUser[n].Password, ((strcmp(value, "") != 0) ? password : value), sizeof(FTPUser[n].Password));
				return true;
			}
			sprintf(temp, "FTPUser[%d].FTPPath", n+1);
			if (strcasecmp(name, temp) == 0) {
				strncpy(FTPUser[n].FTPPath, value, sizeof(FTPUser[n].FTPPath));
				return true;
			}
			sprintf(temp, "FTPUser[%d].Port", n+1);
			if (strcasecmp(name, temp) == 0) {
				if (sscanf(value, "%d", &i) == 1) {
					FTPUser[n].Port = i;
				}
				return true;
			}
			sprintf(temp, "FTPUser[%d].Passive", n+1);
			if (strcasecmp(name, temp) == 0) {
				if (sscanf(value, "%d", &i) == 1) {
					FTPUser[n].Passive = i;
				}
				return true;
			}
		}

		for(n = 0; n < MAXNFSUSERS; n++) {
			sprintf(temp, "NFSUser[%d].Host", n+1);
			if (strcasecmp(name, temp) == 0) {
				strncpy(NFSUser[n].Host, value, sizeof(NFSUser[n].Host));
				return true;
			}
			sprintf(temp, "NFSUser[%d].Mountpoint", n+1);
			if (strcasecmp(name, temp) == 0) {
				strncpy(NFSUser[n].Mountpoint, value, sizeof(NFSUser[n].Mountpoint));
				return true;
			}
		}
	}

	return false;
}

void CSettings::ParseLine(char *line)
{
	char temp[1024], name[1024], value[1024];

	strncpy(temp, line, sizeof(temp));

	char * eq = strchr(temp, '=');

	if(!eq) return;

	*eq = 0;

	this->TrimLine(name, temp, sizeof(name));
	this->TrimLine(value, eq+1, sizeof(value));

	this->SetSetting(name, value);
}

void CSettings::TrimLine(char *dest, char *src, int size)
{
	int len;
	while (*src == ' ') src++;
	len = strlen(src);
	while (len > 0 && strchr(" \r\n", src[len-1])) len--;
	if (len >= size) len = size-1;
	strncpy(dest, src, len);
	dest[len] = 0;
}
